package br.usp.ime.ingpos.services;

import java.io.Serializable;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.SessionScoped;
import br.usp.ime.ingpos.modelo.Email;

@Component
@SessionScoped
public class EmailService
    implements
        Serializable
{
    private static final long serialVersionUID = 7886620811055669211L;

    public static String PROP_MAIL_SMTP_FROM = "mail.smtp.from";
    public static String PROP_MAIL_SMTP_HOST = "mail.smtp.host";
    public static String PROP_MAIL_SMTP_USER = "mail.smtp.user";
    public static String PROP_MAIL_SMTP_PORT = "mail.smtp.port";
    public static String PROP_MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable";
    public static String PROP_MAIL_SMTP_AUTH = "mail.smtp.auth";
    public static String PROP_MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
    public static String PROP_MAIL_SMTP_SOCKET_FACTORY_PORT = "mail.smtp.socketFactory.port";

    private static final String CONTEXT_ENV = "java:comp/env";
    private static final String CONTEXT_MAIL_SESSION = "mail/Session";
    private static final String SMTP_PROTOCOL = "smtp";
    private static final String FORMATO_TEXTO = "text/html";

    private final Session session;
    private final Transport transporte;

    public EmailService()
        throws EmailException
    {
        try {
            final Context initCtx = new InitialContext();
            final Context envCtx = (Context) initCtx.lookup( CONTEXT_ENV );
            this.session = (Session) envCtx.lookup( CONTEXT_MAIL_SESSION );
            this.transporte = session.getTransport( SMTP_PROTOCOL );
        } catch( NamingException e ) {
            throw new EmailException( e );
        } catch( NoSuchProviderException e ) {
            throw new EmailException( e );
        }
    }

    public EmailService(
        final Session session )
        throws EmailException
    {
        try {
            this.session = session;
            this.transporte = session.getTransport( SMTP_PROTOCOL );
        } catch( NoSuchProviderException e ) {
            throw new EmailException( e );
        }
    }

    public void enviarEmail(
        final Email email )
        throws EmailException
    {
        try {
            final Message message = new MimeMessage( session );
            final int numeroDeDestinatarios = email.getEmailDestinatarios().size();
            final InternetAddress[] enderecosDestinatarios = new InternetAddress[ numeroDeDestinatarios ];

            for( int i = 0; i < numeroDeDestinatarios; i++ ) {
                enderecosDestinatarios[ i ] = new InternetAddress(
                    email.getEmailDestinatarios().get( i ) );
            }

            message.setFrom( new InternetAddress( email.getEmailRemetente() ) );
            message.setRecipients( Message.RecipientType.TO, enderecosDestinatarios );
   //         message.setRecipient( Message.RecipientType.BCC, new InternetAddress( "willen.goulart@gmail.com" ) );

            message.setSubject( email.getAssunto() );
            message.setContent( email.getConteudo(), FORMATO_TEXTO );
            message.setSentDate( new java.util.Date() );

            transporte.connect( email.getHostNome(), email.getUsuario(), email.getSenha() );
            transporte.sendMessage( message, message.getAllRecipients() );
            transporte.close();

        } catch( AddressException e ) {
            throw new EmailException( e );
        } catch( MessagingException e ) {
            throw new EmailException( e );
        }
    }

    public Email construirEmail(
        final String assunto,
        final String conteudo,
        final String... destinatarios )
    {
        final Email email = new Email();
        email.setEmailRemetente( session.getProperty( "mail.smtp.from" ) );
        email.setHostNome( session.getProperty( "mail.smtp.host" ) );
        email.setUsuario( session.getProperty( "mail.smtp.user" ) );

        email.setAssunto( assunto );
        email.setConteudo( conteudo );

        for( String destinatario : destinatarios )
            email.adicionarDestinatario( destinatario );

        return email;
    }
}